Analysis of Accelerometer readings fitted in an elevator

In [34]:
#Import necessary Libraries

#Data Manipulation/Statistics
import pandas as pd
from scipy import stats

#Visualization
import matplotlib.pyplot as plt
import plotly.express as px

#Sensor data analysis
import sensormotion as sm

#Resetting the pandas warnings
pd.options.mode.chained_assignment = None  # default='warn
In [36]:
%%time
#Load the dataset
colnames=['TIMESTAMP', 'X', 'Y', 'Z'] 
df = pd.read_excel('Test Data.xlsx', names=colnames, header=None )
df.head()
Wall time: 52.7 s
Out[36]:
TIMESTAMP X Y Z
0 2018-07-23 08:25:57.470 -0.292969 0.054688 -1.000000
1 2018-07-23 08:25:57.479 -0.035156 -0.019531 -0.976563
2 2018-07-23 08:25:57.490 -0.035156 -0.031250 -1.019531
3 2018-07-23 08:25:57.500 -0.035156 -0.019531 -1.019531
4 2018-07-23 08:25:57.509 -0.031250 -0.031250 -1.023438

In this section, we have selected the data between the timestamp range of "2018-07-23 08:30:00.000" and "2018-07-23 09:40:00.000"

In [3]:
#Change the start and end timeStamp to select data according to the requirement
StartTimestamp = '2018-07-23 08:30:00.000'
EndTimestamp = '2018-07-23 09:40:00.000'
dfTimeUpd =  df[df['TIMESTAMP'].between(StartTimestamp,EndTimestamp)]
dfTimeUpd.head()
Out[3]:
TIMESTAMP X Y Z
24878 2018-07-23 08:30:00.000 -0.019531 -0.031250 -1.039063
24879 2018-07-23 08:30:00.010 -0.023438 -0.015625 -1.035156
24880 2018-07-23 08:30:00.019 -0.039063 -0.050781 -1.039063
24881 2018-07-23 08:30:00.029 -0.035156 -0.042969 -1.039063
24882 2018-07-23 08:30:00.039 -0.035156 -0.031250 -1.039063

Raw Data Plots of X, Y and Z

In [4]:
fig, ax = plt.subplots(nrows=3, ncols=1, figsize=(15,10))

ax[0].set_title('Raw X')
ax[0].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['X'], linewidth=0.5, color='k')

ax[1].set_title('Raw Y')
ax[1].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Y'], linewidth=0.5, color='k')

ax[2].set_title('Raw Z')
ax[2].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z'], linewidth=0.5, color='k')

fig.subplots_adjust(hspace=.5)

Let's focus on the Z-axis values values as the accelerometer is fitted in an elevator

In [37]:
#Visualize the data for Z axis
fig = px.line(dfTimeUpd, x='TIMESTAMP', y='Z', title='Finding visual patterns along Z-axis')

fig.update_xaxes(rangeslider_visible=True)
fig.show()
Observation:
  1. The high peaks can be zoomed in the figure and it can be noticed that there are three main phases in these readings i.e. acceleration, constant velocity and deacceleration.

  2. Zooming in the lower picks it can be seen that a lot of noises are also picked in the readings.

Note: Please make use of the Timestamp slider or select the area in the graph to move around the datapoints.

Z-normalize the data

Let's normalize the data to reduce noise. To accomplish this we will make use of Z-score and create a new column 'Z_New'

In [38]:
dfTimeUpd['Z_New'] = stats.zscore(dfTimeUpd['Z'])

Plot the graphs for Raw Z-axis value and new Z-axis value after Z-normalize

In [39]:
fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(15,10))

ax[0].set_title('Raw Z-axis')
ax[0].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z'], linewidth=0.5, color='k')

ax[1].set_title('New Z-axis after Z-normalize')
ax[1].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_New'], linewidth=0.5, color='k')

fig.subplots_adjust(hspace=.5)

Using a Low Pass filter to remove noise

Test the filter at various frequencies

In [40]:
S_range = [10,5,1,0.1]
col_nam = []
for x in S_range:
    b, a = sm.signal.build_filter(frequency=x,
                              sample_rate=100,
                              filter_type='low',
                              filter_order=4)
    col_name = "Z_Filtered_"+str(x)
    dfTimeUpd[col_name] = sm.signal.filter_signal(b, a, signal=dfTimeUpd['Z_New'])
In [41]:
# Create plots with overlaid filtered signals (Red Color)
fig, ax = plt.subplots(nrows=4, ncols=1, figsize=(10,9))

ax[0].set_title('Z_Filtered_10')
ax[0].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_New'], linewidth=0.3, color='k')
ax[0].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_Filtered_10'], linewidth=0.8, color='r')

ax[1].set_title('Z_Filtered_5')
ax[1].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_New'], linewidth=0.3, color='k')
ax[1].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_Filtered_5'], linewidth=0.9, color='r')

ax[2].set_title('Z_Filtered_1')
ax[2].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_New'], linewidth=0.3, color='k')
ax[2].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_Filtered_1'], linewidth=0.9, color='r')

ax[3].set_title('Z_Filtered_0.1')
ax[3].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_New'], linewidth=0.3, color='k')
ax[3].plot(dfTimeUpd['TIMESTAMP'], dfTimeUpd['Z_Filtered_0.1'], linewidth=0.9, color='r')

fig.subplots_adjust(hspace=.5)
Observation:
  1. 10 and 5Hz filter threshold provided better results

Create zoomable visualization at 5Hz

In [42]:
#Visualize the data for Z axis
fig = px.line(dfTimeUpd, x='TIMESTAMP', y='Z_Filtered_5', title='Finding visual patterns along Z-axis filtered at 5Hz')

fig.update_xaxes(rangeslider_visible=True)
fig.show()
Observation:

1.Based on the initial analysis, it can be considered that the thin bars between 10 to -10 range are normal up and down movement of the elevator.

  1. The long bars needs to be further investigated.
  2. The constant or little peaks around 0 is tht static position of elevator.

The above analysis could be utilized for further analysis. If the observation above are true, then a Classification model could be further trained to inform if a specific pattern is followed by the elevator.

In [ ]: